﻿using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Altairis.Web.UI.WebControls {
    public class IconHyperLink : CompositeControl {
        private const string ResourceNameFormat = "Altairis.Web.UI.Resources.Icons.{0}.png";

        public IconHyperLink() {
            this.Icon = IconType.NoIcon;
            this.Mode = IconDisplayMode.IconLeft;
            this.IconMargin = ".5ex";
        }

        /// <summary>
        /// Gets or sets the URL to link to when the <see cref="T:Altairis.Web.UI.WebControls.IconHyperLink"/> control is clicked.
        /// </summary>
        /// <value></value>
        /// <returns>
        /// The URL to link to when the <see cref="T:Altairis.Web.UI.WebControls.IconHyperLink"/> control is clicked. The default value is an empty string ('').
        /// </returns>
        [Category("Navigation"), DefaultValue(""), Bindable(true), UrlProperty]
        [Description("The URL to link to when the control is clicked.")]
        public string NavigateUrl {
            get { return (string)(this.ViewState["NavigateUrl"] ?? string.Empty); }
            set { this.ViewState["NavigateUrl"] = value; }
        }

        /// <summary>
        /// Gets or sets the target window or frame in which to display the Web page content linked to when the <see cref="T:Altairis.Web.UI.WebControls.IconHyperLink"/> control is clicked.
        /// </summary>
        /// <value></value>
        /// <returns>
        /// The target window or frame to load the Web page linked to when the <see cref="T:Altairis.Web.UI.WebControls.IconHyperLink"/> control is clicked. Values must begin with a letter in the range of a through z (case-insensitive), except for the special values listed in the following table, which begin with an underscore.
        /// _blank
        /// Renders the content in a new window without frames.
        /// _parent
        /// Renders the content in the immediate frameset parent.
        /// _search
        /// Renders the content in the search pane.
        /// _self
        /// Renders the content in the frame with focus.
        /// _top
        /// Renders the content in the full window without frames.
        /// Note:
        /// Check your browser documentation to determine if the
        /// _search value is supported.  For example, Microsoft Internet Explorer 5.0 and later support the _search target value.
        /// The default value is an empty string ("").
        /// </returns>
        [Category("Navigation"), DefaultValue(""), TypeConverter(typeof(TargetConverter))]
        [Description("Gets or sets the target window or frame in which to display the Web page content linked to when the control is clicked.")]
        public string Target {
            get { return (string)(this.ViewState["Target"] ?? string.Empty); }
            set { this.ViewState["Target"] = value; }
        }

        /// <summary>
        /// Gets or sets the text caption for the <see cref="T:Altairis.Web.UI.WebControls.IconHyperLink"/> control.
        /// </summary>
        /// <value></value>
        /// <returns>
        /// The text caption for the <see cref="T:Altairis.Web.UI.WebControls.IconHyperLink"/> control. The default value is an empty string ("").
        /// </returns>
        [Category("Appearance"), DefaultValue(""), Bindable(true), Localizable(true)]
        [Description("Gets or sets the text caption for the control.")]
        public string Text {
            get { return (string)(this.ViewState["Text"] ?? string.Empty); }
            set { this.ViewState["Text"] = value; }
        }

        /// <summary>
        /// Gets of sets the name of icon to be displayed.
        /// </summary>
        /// <value>Name of icon to be displayed.</value>
        [Category("Appearance"), Themeable(true), Bindable(true), DefaultValue(IconType.NoIcon)]
        [Description("Name of icon to be displayed.")]
        public IconType Icon {
            get { return (IconType)(this.ViewState["Icon"] ?? IconType.NoIcon); }
            set { this.ViewState["Icon"] = value; }
        }

        /// <summary>
        /// Gets or sets the distance between icon and text label.
        /// </summary>
        /// <value>The distance between icon and text label.</value>
        [Category("Appearance"), Themeable(true), DefaultValue(".5ex")]
        public string IconMargin {
            get { return (string)this.ViewState["IconMargin"]; }
            set { this.ViewState["IconMargin"] = value; }
        }

        /// <summary>
        /// Gets or sets the display mode.
        /// </summary>
        /// <value>The display mode.</value>
        [Category("Appearance"), Themeable(true), DefaultValue(IconDisplayMode.IconLeft)]
        public IconDisplayMode Mode {
            get { return (IconDisplayMode)(this.ViewState["Mode"] ?? IconDisplayMode.IconLeft); }
            set { this.ViewState["Mode"] = value; }
        }

        protected override void CreateChildControls() {
            switch (this.Mode) {
                case IconDisplayMode.IconLeft:
                    this.AddIconLink();
                    this.AddTextLink();
                    break;
                case IconDisplayMode.IconRight:
                    this.AddTextLink();
                    this.AddIconLink();
                    break;
                case IconDisplayMode.IconOnly:
                    this.AddIconLink();
                    break;
                default: // DisplayMode.TextOnly:
                    this.AddTextLink();
                    break;
            }
        }

        private void AddIconLink() {
            // If no icon specified, do nothing
            if (this.Icon == IconType.NoIcon) return;

            // Create new hyperlink and setup basic properties
            HyperLink link = new HyperLink();
            if (this.Enabled) link.NavigateUrl = this.NavigateUrl;
            link.Text = this.Text;
            link.Target = this.Target;
            link.Width = Unit.Pixel(16);
            link.Height = Unit.Pixel(16);
            link.ToolTip = this.ToolTip;
            link.Enabled = this.Enabled;

            // Add margin between text and icon
            if (this.Mode == IconDisplayMode.IconLeft) link.Style.Add("margin-right", this.IconMargin);
            else if (this.Mode == IconDisplayMode.IconRight) link.Style.Add("margin-left", this.IconMargin);

            // Set image source to web resource to this item
            link.ImageUrl = this.Page.ClientScript.GetWebResourceUrl(
                this.GetType(),
                string.Format(ResourceNameFormat, this.Icon));

            // Add to child controls
            this.Controls.Add(link);
        }

        private void AddTextLink() {
            // If no text specified, do nothing
            if (string.IsNullOrEmpty(this.Text)) return;

            // Create new hyperlink and setup basic properties
            var link = new EllipsisHyperLink();
            if (this.Enabled) link.NavigateUrl = this.NavigateUrl;
            link.Text = this.Text;
            link.Target = this.Target;
            link.Enabled = this.Enabled;

            // Add to child controls
            this.Controls.Add(link);
        }

    }
}
